using System.Collections.Generic;
using UnityEngine;

public class ObjectPool
{
    // /**
    //  * 我们希望不同的物体可以被分开存储，在这种情况下使用字典是最合适的
    //  * 所以声明一个字典objectPool作为对象池主体，以字符串类型的物体的名字作为key
    //  * 使用队列存储物体来作为value,这里使用队列只是因为入队和出队的操作较为方便,也可以换成其他集合方式
    //  * 然后实例化这个字典以备后续使用
    //  * /
    private static Dictionary<string, Queue<GameObject>> objectPools = new Dictionary<string, Queue<GameObject>>(); // 对象池字典
    private static GameObject pool; // 为了不让窗口杂乱，声明一个对象池父物体，作为所有生成物体的父物体

    public static GameObject GetObject(GameObject prefab)
    {
        if (pool == null) pool = new GameObject("ObjectPool"); // 如果对象池父物体不存在，则创建一个新的对象池父物体
        GameObject childPool = GameObject.Find(prefab.name + "Pool"); // 查找该对象的子对象池
        if (!childPool)
        {
            childPool = new GameObject(prefab.name + "Pool"); // 如果该对象的子对象池不存在，则创建一个新的子对象池
            childPool.transform.SetParent(pool.transform); // 将该子对象池加入对象池父物体中
        }

        GameObject _object = null;

        if (objectPools.ContainsKey(prefab.name) && objectPools[prefab.name].Count > 0)
        {
            //从对象池中取出一个对象实例
            _object = objectPools[prefab.name].Dequeue();
        }
        if(_object == null){
            // 如果对象池中没有这种类型的对象，实例化一个新对象
            _object = GameObject.Instantiate(prefab);
        }
        _object.SetActive(true); // 激活对象
        _object.transform.SetParent(childPool.transform); // 将新的对象加入该对象的子对象池中
        return _object;

    }
    public static void PushObject(GameObject prefab) // 将对象加入对象池中
    {
        //获取对象的名称，因为实例化的物体名都会加上"(Clone)"的后缀，需要先去掉这个后缀才能使用名称查找
        string _name = prefab.name.Replace("(Clone)", string.Empty);
        if (!objectPools.ContainsKey(_name))
            objectPools.Add(_name, new Queue<GameObject>()); // 如果对象池中没有该对象，则创建一个新的对象池
        objectPools[_name].Enqueue(prefab); // 将对象加入对象池中
        prefab.SetActive(false); // 将对象禁用
    }
}
